/*
 * Copyright (c) 2013, SRI International
 * All rights reserved.
 * Licensed under the The BSD 3-Clause License;
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 * 
 * http://opensource.org/licenses/BSD-3-Clause
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 
 * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 * 
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * 
 * Neither the name of the aic-web-praise nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package com.sri.ai.lpitools.gwtgui.client.util;

import java.util.ArrayList;
import java.util.List;

import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONParser;
import com.google.gwt.json.client.JSONString;
import com.google.gwt.json.client.JSONValue;
import com.sri.ai.lpitools.cobra.gwtutil.dataobjects.shared.EvidenceInfo;
import com.sri.ai.lpitools.cobra.gwtutil.dataobjects.shared.ModelInfo;
import com.sri.ai.lpitools.cobra.gwtutil.dataobjects.shared.QueryInfo;
import com.sri.ai.lpitools.cobra.gwtutil.dataobjects.shared.UserInfo;

public class JSONUtil {
	
	public static String getStringValue(JSONObject jso, String key) {
		JSONValue value = jso.get(key);
		if (value != null) {
			JSONString stringObj = value.isString();
			if (stringObj != null) {
				return stringObj.stringValue();
			}
		}
		
		//oops, asked for a key I didn't have, or that wasn't a string
		return null;
	}
	
	
	/**
	 * This function takes in a JSONValue and will return a cleaned string object
	 * A cleaned string is one with any " removed and remove any ' at start or end of string
	 * @param value
	 * @return
	 */
	public static String cleanJSONValue(JSONValue value){
		
		if (value == null) {
			return null;
		}
		
		String str = value.toString().replaceAll("\"", "");
		
		if(str.charAt(0) == '\''){
			str = str.substring(1);
		}
		
		if(str.charAt(str.length()-1) == '\''){
			str = str.substring(0, str.length()-1);
		}

		return str;
	}
	/**
	 * This function takes in a JSONValue and will return a cleaned string object
	 * A cleaned string is one with any " removed and remove any ' at start or end of string
	 * @param value
	 * @return
	 */
	public static String cleanString(String value){
		String str = value.replaceAll("\"", "");
		
	
//		if(str.charAt(0) == '\''){
//			str = str.substring(1);
//		}
//		
//		if(str.charAt(str.length()-1) == '\''){
//			str = str.substring(0, str.length()-1);
//		}

		return str;
	}	
	/**
	 * This function takes in a JSONArray and return an array of cleaned Strings
	 * @param jArray
	 * @return
	 */
	public static List<String> cleanJSONArray(JSONArray jArray){
		int size = jArray.size();
		
		List<String> array =new ArrayList<String>();
		for(int i = 0; i< size; i++){
			String value = cleanJSONValue(jArray.get(i));
			array.add(i, value);
		}
		return array;
	}
	
	/**
	 * This function is user to trun a JSON string representation of a UserInfo object into an UserInfo object
	 * @param user
	 * @return
	 */
	public static UserInfo getUserInfo(String user){
		JSONObject userJson = (JSONObject) JSONParser.parseStrict(user);
		String name = cleanString(userJson.get("user").toString());
		boolean isAdmin = Boolean.parseBoolean(cleanString(userJson.get("admin").toString()));
		UserInfo userInfo = new UserInfo();
		userInfo.setUser(name);
		userInfo.setAdmin(isAdmin);
		
		return userInfo;
	}
	
	/**
	 * This function is user to trun a JSON list string representation of a list of UserInfo object into a list of UserInfo object
	 * @param user
	 * @return
	 */
	public static List<UserInfo> getUserInfoList(String userList){
		List<UserInfo> userInfoList = new ArrayList<UserInfo>();
		JSONArray jsv = (JSONArray) JSONParser.parseStrict(userList);
		int size = jsv.size();
		for(int i = 0; i< size; i++){
			JSONObject userJson = (JSONObject) JSONParser.parseStrict(jsv.get(i).toString());
			String name = cleanString(userJson.get("user").toString());
			boolean isAdmin = Boolean.parseBoolean(cleanString(userJson.get("admin").toString()));
			UserInfo userInfo = new UserInfo();
			userInfo.setUser(name);
			userInfo.setAdmin(isAdmin);
			userInfoList.add(userInfo);
		}
		return userInfoList;
	}
	
	/**
	 * This function is user to trun a JSON list string representation of a list of UserInfo object into a list of UserInfo object
	 * @param user
	 * @return
	 */
	public static List<QueryInfo> getQueryInfoList(String queryList){
		List<QueryInfo> queryInfoList = new ArrayList<QueryInfo>();
		JSONArray jsv = (JSONArray) JSONParser.parseStrict(queryList);
		int size = jsv.size();
		for(int i = 0; i< size; i++){
			JSONObject queryJson = (JSONObject) JSONParser.parseStrict(jsv.get(i).toString());
			String name = cleanString(queryJson.get("user").toString());
			String queryTitle = cleanString(queryJson.get("queryTitle").toString());
			String query = cleanString(queryJson.get("query").toString());
			QueryInfo queryInfo = new QueryInfo();
			queryInfo.setUser(name);
			queryInfo.setQueryTitle(queryTitle);
			queryInfo.setQuery(query);
			queryInfoList.add(queryInfo);
		}
		return queryInfoList;
	}
	/**
	 * This function is user to trun a JSON string representation of a UserInfo object into an UserInfo object
	 * @param user
	 * @return
	 */
	public static QueryInfo getQueryInfo(String query){
		JSONObject queryJson = (JSONObject) JSONParser.parseStrict(query);
		String name = cleanString(queryJson.get("user").toString());
		String queryTitle = cleanString(queryJson.get("queryTitle").toString());
		String queryValue = cleanString(queryJson.get("query").toString());
		QueryInfo queryInfo = new QueryInfo();
		queryInfo.setUser(name);
		queryInfo.setQueryTitle(queryTitle);
		queryInfo.setQuery(queryValue);
		
		return queryInfo;
	}
	
	
	/**
	 * This function is user to trun a JSON list string representation of a list of UserInfo object into a list of UserInfo object
	 * @param user
	 * @return
	 */
	public static List<EvidenceInfo> getEvidenceInfoList(String evidenceList){
		List<EvidenceInfo> evidenceInfoList = new ArrayList<EvidenceInfo>();
		JSONArray jsv = (JSONArray) JSONParser.parseStrict(evidenceList);
		int size = jsv.size();
		for(int i = 0; i< size; i++){
			JSONObject evidenceJson = (JSONObject) JSONParser.parseStrict(jsv.get(i).toString());
			String name = cleanString(evidenceJson.get("user").toString());
			String evidenceTitle = cleanString(evidenceJson.get("evidenceTitle").toString());
			String evidence= cleanString(evidenceJson.get("evidence").toString());
			EvidenceInfo evidenceInfo = new EvidenceInfo();
			evidenceInfo.setUser(name);
			evidenceInfo.setEvidenceTitle(evidenceTitle);
			evidenceInfo.setEvidence(evidence);
			evidenceInfoList.add(evidenceInfo);
		}
		return evidenceInfoList;
	}
	/**
	 * This function is user to trun a JSON string representation of a UserInfo object into an UserInfo object
	 * @param user
	 * @return
	 */
	public static EvidenceInfo getEvidenceInfo(String evidence){
		JSONObject evidenceJson = (JSONObject) JSONParser.parseStrict(evidence);
		String name = cleanString(evidenceJson.get("user").toString());
		String evidenceTitle = cleanString(evidenceJson.get("evidenceTitle").toString());
		String evidenceValue = cleanString(evidenceJson.get("evidence").toString());
		EvidenceInfo evidenceInfo = new EvidenceInfo();
		evidenceInfo.setUser(name);
		evidenceInfo.setEvidenceTitle(evidenceTitle);
		evidenceInfo.setEvidence(evidenceValue);
		
		return evidenceInfo;
	}
	
	/**
	 * This function is user to turn a JSON list string representation of a list of UserInfo object into a list of UserInfo object
	 * @param user
	 * @return
	 */
	public static List<ModelInfo> getModelInfoList(String modelList){
		List<ModelInfo> modelInfoList = new ArrayList<ModelInfo>();
		JSONArray jsv = (JSONArray) JSONParser.parseStrict(modelList);
		int size = jsv.size();
		for(int i = 0; i< size; i++){
			JSONObject modelJson = (JSONObject) JSONParser.parseStrict(jsv.get(i).toString());
			String name = cleanString(modelJson.get("user").toString());
			String modelTitle = cleanString(modelJson.get("modelTitle").toString());
			String modelValue= cleanString(modelJson.get("modelText").toString());
			String shortDescription= cleanString(modelJson.get("shortDescription").toString());
			ModelInfo modelInfo = new ModelInfo();
			modelInfo.setUser(name);
			modelInfo.setModelText(modelValue);
			modelInfo.setModelTitle(modelTitle);
			modelInfo.setShortDescription(shortDescription);
			modelInfoList.add(modelInfo);
		}
		return modelInfoList;
	}
	/**
	 * This function is user to run a JSON string representation of a UserInfo object into an UserInfo object
	 * @param user
	 * @return
	 */
	public static ModelInfo getModelInfo(String model){
		JSONObject modelJson = (JSONObject) JSONParser.parseStrict(model);
		String name = cleanString(modelJson.get("user").toString());
		String modelTitle = cleanString(modelJson.get("modelTitle").toString());
		String modelValue= cleanString(modelJson.get("modelText").toString());
		String shortDescription= cleanString(modelJson.get("shortDescription").toString());
		ModelInfo modelInfo = new ModelInfo();
		modelInfo.setUser(name);
		modelInfo.setModelText(modelValue);
		modelInfo.setModelTitle(modelTitle);
		modelInfo.setShortDescription(shortDescription);
		
		return modelInfo;
	}
}
